package asteroids.statement;

import asteroids.*;
import asteroids.model.programs.*;
import asteroids.statement.Statement.StatementType;
import asteroids.expression.*;

public class IfElseStatement extends Statement {

	Expression exp;
	Statement s1, s2;

	public IfElseStatement(Expression e, Statement s1, Statement s2) {
		if (e == null)
			e = new asteroids.expression.BooleanLiteral(false);
		if (s1 == null)
			s1 = new Print(new asteroids.expression.BooleanLiteral(false));
		if (s2 == null)
			s2 = new Print(new asteroids.expression.BooleanLiteral(false));
		this.s1 = s1;
		this.s2 = s2;
		if (e instanceof Expression) {
			this.exp = e;
		} else {
			this.exp = new asteroids.expression.BooleanLiteral(false);
		}

	}

	public void execute(Program program) {
		if (s1.finished) {
			s1.loop();
		}
		if (s2.finished) {
			s2.loop();
		}

		if (this.exp instanceof BooleanExpression) {
			if (((BooleanExpression) this.exp).getValue(program)) {
				this.s1.execute(program);
				if ((s1.getType() == StatementType.ACTION) || (s1.getBreaker())) {
					this.setBreaker(true);
					s1.setBreaker(false);

				}
			} else {
				this.s2.execute(program);
				if ((s2.getType() == StatementType.ACTION) || (s2.getBreaker())) {
					this.setBreaker(true);
					s2.setBreaker(false);

				}
			}

		} else if (this.exp instanceof Variable
				&& ((Variable) this.exp).getRef(program) instanceof BooleanExpression) {
			if (((Boolean) ((Variable) this.exp).getValue(program))) {
				this.s1.execute(program);
				if ((s1.getType() == StatementType.ACTION) || (s1.getBreaker())) {
					this.setBreaker(true);
					s1.setBreaker(false);
				}
			} else {
				this.s2.execute(program);
				if ((s2.getType() == StatementType.ACTION) || (s2.getBreaker())) {
					this.setBreaker(true);
					s2.setBreaker(false);

				}
			}
		} else {
			// die
		}
		if (!this.getBreaker()) {
			finished = true;
		}
	}

	@Override
	public int getSize() {
		return 1;
	}

}
